package org.tacticalTroopers.jme.server;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.tacticalTroopers.jme.common.message.Command;
import org.tacticalTroopers.jme.server.object.ElementFactory;
import org.tacticalTroopers.jme.server.object.ServerBullet;
import org.tacticalTroopers.jme.server.object.ServerElement;
import org.tacticalTroopers.jme.server.object.ServerGameArea;
import org.tacticalTroopers.jme.server.object.ServerPlayer;
import org.tacticalTroopers.jme.server.score.ScoreManager;
import org.tacticalTroopers.jme.server.team.TeamManager;

public class GameManager {

	final static Log log = LogFactory.getLog(GameManager.class);

	TeamManager teamManager;
	ScoreManager scoreManager;
	ElementFactory ef ;
	List<ServerPlayer> players = new ArrayList<ServerPlayer>();

	ServerGameArea gameArea;
	TacticalTroopersServer tacticalTrooperServer;
	public GameManager(TacticalTroopersServer tacticalTrooperServer){
		this.tacticalTrooperServer = tacticalTrooperServer;
		teamManager = new TeamManager();
		scoreManager = new ScoreManager(tacticalTrooperServer);
		scoreManager.setTeamManager(teamManager);
		ef = ElementFactory.getInstance();
	}

	public void step(Integer milliseconds) {
		handleCommand();
		gameArea.step(milliseconds);		
	}


	public ServerPlayer createPlayer() {
		ServerPlayer player = ef.creatPlayer();
		player.setState(ServerPlayer.State.LIVE);
		player.addAction(bulletHitPlayer);
		teamManager.add(player);
		scoreManager.add(player);
		player.setPosition(gameArea.getMap().getRespownPosition(player.getTeam()));
		gameArea.addDynamicElement(player);
		players.add(player);
		return player;
	}

	public void removePlayer(ServerPlayer player) {
		gameArea.removeElement(player);
		players.remove(player);
		teamManager.remove(player);
		scoreManager.remove(player);
	}


	public ServerElement createBox() {
		ServerElement box = ef.createElement();
		box.setSize(1f, 1f, 1f);
		box.setPosition(0f,5f,3f);

		box.setMass(1f);
		box.addAction(bulletHitBox);
		gameArea.addDynamicElement(box);
		//box.setRotation(0f, FastMath.PI/2, 0f);
		return box;
	}

	void handleCommand() {
		for (ServerPlayer player : players){
			if(player.getState()==ServerPlayer.State.LIVE){
				Command command  = player.getCommand();
				if(command.getOrder()!=null){
					if(command.getOrder().equals(Command.SWITCH_TEAM)){
						if(player.getAttributeBoolean("canSwitchTeam", true)){
							log.info("TEAMSWITH");
							teamManager.switchTeam(player);
							player.setAttribute("canSwitchTeam",false);
							player.addAction(new OneShotGameAction() {

								@Override
								public void soleAction(ServerElement p) {
									p.setAttribute("canSwitchTeam", true);
								}
							}.setDelay(1000));
						}
					}else if(command.getOrder().equals(Command.RESET)){
						player.setAttribute("enable", false);
						player.addAction(playerRespown);
					}
				}
				if(command.getFire()&&player.isAllowedTofire()){
					//log.debug("fire");
					command.setFire(false);
					ServerBullet b = ef.createBullet();
					//bullets.add(b);
					b.setOwner(player);
					b.setOriantation(player.getOriantation());
					b.setPosition(player.getFirePosition());
					//physicer.addDynamicElement(b,50f);
					gameArea.addDynamicElement(b,4f);
					b.addAction(bulletLife);
					player.setAllowedToFire(false);
					player.addAction( new OneShotGameAction() {
						@Override
						public void soleAction(ServerElement element) {
							((ServerPlayer)element).setAllowedToFire(true);
						}
					}.setDelay(500));
				}
				if(command.getAccel()!=0){
					player.setAccel(command.getAccel());
				}
				if(command.getTurn()!=0f){
					player.setTurn(command.getTurn());
				}
				if(command.getStraf()!=0f){
					player.setStraf(command.getStraf());
				}
			}
		}

	}


	public void setGameArea(ServerGameArea gameArea) {
		this.gameArea = gameArea;
	}



	GameAction bulletHitPlayer = new GameAction() {

		@Override
		public void action(ServerElement element,Integer milliseconds) {
			ServerPlayer player = (ServerPlayer)element;
			if(player.getAttributeBoolean("enable",true)){
				List<ServerElement> list = player.getCollidees().get(ServerBullet.class);
				if(list!=null&&list.size()>0){
					ServerBullet bullet = (ServerBullet)list.get(0);
					if(bullet.getOwner()!=player){
						player.setAttribute("enable", false);
						scoreManager.playerHit(bullet.getOwner(),player,bullet);
						player.addAction(playerRespown);
					}else{
						log.info("autoKill");
						log.info("bullet:"+bullet.toString());
						log.info("player:"+player.toString());

					}
				}
			}
		}
	};

	OneShotGameAction playerRespown = new OneShotGameAction() {

		@Override
		public void soleAction(ServerElement p) {
			ServerPlayer player = (ServerPlayer)p;
			player.setPosition(gameArea.getMap().getRespownPosition(player.getTeam()));
			player.setRotation(0f, 0f, 0f);
			player.setAttribute("enable", true);
		}

	};



	GameAction bulletHitBox = new GameAction() {

		@Override
		public void action(ServerElement element,Integer milliseconds) {
			List<ServerElement> list = element.getCollidees().get(ServerBullet.class);
			if(list!=null&&list.size()>0&&element.getAttributeBoolean("enable",true)){
				//log.info("[COLLIDE]");

				element.setAttribute("enable", false);
				/*final ServerBullet bullet = ((ServerBullet)list.get(0));
				System.out.println("Hit");
				scoreManager.playerHit(bullet.getOwner(), element, bullet);
				 */
				element.addAction(new OneShotGameAction() {
					@Override
					public void soleAction(ServerElement element) {
						System.out.println("Place");
						element.setPosition(1f, 5f, 1f);
						element.setAttribute("enable", true);
					}
				}.setDelay(500));

			}
		}
	};


	GameAction bulletLife = new GameAction() {

		@Override
		public void action(ServerElement element,Integer milliseconds) {
			ServerBullet b = (ServerBullet)element;
			if(b.getTimeToLive()>0){
				if(!b.getCollidees().isEmpty()){
					b.setNbCollisionAllowed(b.getNbCollisionAllowed()-1);
					if(b.getNbCollisionAllowed()<0){
						//deleteElement(b);
						gameArea.removeElement(b);
					}
				}
			}else{
				//deleteElement(b);
				gameArea.removeElement(b);
			}
			b.decrementTimeToLive();
		}
	};
	public TeamManager getTeamManager() {
		return teamManager;
	}



	/*
	void handleHitedPlayer() {
		for(ServerPlayer player : players){
			List<ServerElement> list = player.getCollidees().get(ServerBullet.class);
			if(list!=null&&list.size()>0){
				ServerBullet bullet = (ServerBullet)list.get(0);
				bullet.getOwner().getScore().addPoint();

				player.setState(ServerPlayer.State.DEAD);
				player.addAction(new OneShotGameAction() {

					@Override
					public Integer getDelay() {
						return 50;
					}

					@Override
					public void delayedAction(ServerElement p) {

						ServerPlayer player = (ServerPlayer)p;
						player.setPosition(gameArea.getMap().getRespownPosition(player.getTeam()));
						player.setState(ServerPlayer.State.LIVE);

					}


				});
			}

		}
	}
	 */


	/*
		List<ServerElement> bulletToRemove = new ArrayList<ServerElement>();
		void deleteElement(ServerElement b){
			gameArea.removeElement(b);
			bulletToRemove.add(b);
		}
	 */
	/*
		void handleBullets() {
			bulletToRemove.clear();
			for (ServerBullet b : bullets){
				if(b.getTimeToLive()>0){
					if(!b.getCollidees().isEmpty()){
						b.setNbCollisionAllowed(b.getNbCollisionAllowed()-1);
						if(b.getNbCollisionAllowed()<0){
							deleteElement(b);
						}
					}
				}else{
					deleteElement(b);
				}
				b.decrementTimeToLive();
			}
			bullets.removeAll(bulletToRemove);
		}

	 */



}
